package translinkApp.Activities;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

import translinkApp.Adaptors.GoCardTransactionArrayAdapter;
import translinkApp.Data.GoCard.GoCardTransaction;
import translinkApp.Data.Utils.Functions;
import translinkApp.DataTypes.GoCard.GoCardInfo;
import translinkApp.DataTypes.GoCard.GoCardInfoBadReadException;
import translinkApp.DataTypes.Threads.ErrorObject;
import translinkApp.DataTypes.Threads.ProgressAsyncTask;
import translinkApp.Utilities.EmailContent;
import translinkApp.Utilities.Utils;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class GoCardInfoActivity extends Activity {

	private TextView gocardBalanceText;
	private TextView gocardTypeText;
	private TextView gocardIssueText;
	private TextView gocardExpireText;
	private TextView gocardBalanceAsOfText;
	private GoCardInfo info;
	private ArrayList<GoCardTransaction> transactions;
	private String cardNumValue;
	private String cardPassValue;

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {

		transactions = savedInstanceState.getParcelableArrayList("historyValues");
		loadHistory(transactions);
		super.onRestoreInstanceState(savedInstanceState);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		outState.putParcelableArrayList("historyValues", transactions);
		super.onSaveInstanceState(outState);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.gocardinfo);

		info = null;

		gocardBalanceText = (TextView) findViewById(R.id.gocardBalanceText);
		gocardTypeText = (TextView) findViewById(R.id.gocardTypeText);
		gocardIssueText = (TextView) findViewById(R.id.gocardIssueText);
		gocardExpireText = (TextView) findViewById(R.id.gocardExpireText);
		gocardBalanceAsOfText = (TextView) findViewById(R.id.gocardBalanceAsOfText);
		Button loadHistoryButton = (Button) findViewById(R.id.gocardHistoryButton);
		loadHistoryButton.setOnClickListener(loadHistoryButtonListener);

		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());

		cardNumValue = prefs.getString("cardNum", null);
		cardPassValue = prefs.getString("cardPass", null);
		info = (GoCardInfo) getLastNonConfigurationInstance();
		transactions = null;

		if (info != null) {
			setInfoData(info);
		} else {

			loadCardData();
		}

	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		return info;
	}

	OnClickListener loadHistoryButtonListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			new ObtainGoCardHistoryTask(GoCardInfoActivity.this).execute();
		}
	};

	private void loadHistory(ArrayList<GoCardTransaction> transactions) {

		if (transactions != null) {
			ListView list = (ListView) findViewById(R.id.gocardHistoryList);

			GoCardTransactionArrayAdapter adaptor = new GoCardTransactionArrayAdapter(
					GoCardInfoActivity.this, transactions);
			list.setAdapter(adaptor);

			this.transactions = transactions;
		}
	}

	private void setInfoData(GoCardInfo info) {

		this.info = info;
		gocardBalanceText.setText(info.getBalance());
		gocardBalanceAsOfText.setText("As of " + info.getBalanceTime());
		gocardTypeText.setText(info.getPassengerType());
		gocardIssueText.setText(info.getIssueDate());
		gocardExpireText.setText(info.getExpiryDate());
	}

	private void loadCardData() {

		if (cardNumValue == null) {
			AlertDialog showDialog = Utils.showAlertDialog(GoCardInfoActivity.this,
					"You have not set your Go-Card settings, please set this under settings.");
			showDialog.setOnDismissListener(new OnDismissListener() {

				@Override
				public void onDismiss(DialogInterface dialog) {
					finish();
				}
			});
		} else {

			if (Utils.isOnline(this)) {

				new ObtainGoCardDetailsTask(this).execute();

			} else {
				finish();
			}
		}
	}

	private class ObtainGoCardDetailsTask extends ProgressAsyncTask<GoCardInfo> {

		public ObtainGoCardDetailsTask(Context c) {
			super(c, "Please wait...", "Loading Go-Card information");

		}

		protected ErrorObject<GoCardInfo> doInBackground(String... params) {
			ErrorObject<GoCardInfo> infoWithError = new ErrorObject<GoCardInfo>();
			GoCardInfo info = null;
			try {
				info = new GoCardInfo(cardNumValue, cardPassValue);
			} catch (Exception e) {
				infoWithError.setException(e);
			}
			infoWithError.setItem(info);

			return infoWithError;
		}

		protected void onPostExecute(final ErrorObject<GoCardInfo> result) {
			super.onPostExecute(result);
			
			if (!result.hasException()) {
				setInfoData(result.getItem());
			} else {
				final TextView message = new TextView(GoCardInfoActivity.this);
				message.setPadding(20, 20, 20, 20);
				message.setTextSize(18f);
				message.setTextColor(Color.WHITE);

				final SpannableString s = new SpannableString(result.getException().getMessage());

				Linkify.addLinks(s, Linkify.WEB_URLS);
				message.setText(s);
				message.setMovementMethod(LinkMovementMethod.getInstance());

				Builder b = new AlertDialog.Builder(GoCardInfoActivity.this)
						.setTitle("Go card issue").setCancelable(true)
						.setIcon(android.R.drawable.ic_dialog_info).setPositiveButton("Ok", null)
						.setView(message);

				if (result.getException() instanceof GoCardInfoBadReadException) {
					b.setNegativeButton("Email developer", new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {

							EmailContent c = new EmailContent();
							c.setBody(((GoCardInfoBadReadException) result.getException()).htmlData);
							c.setSendAddress("lachlandevelopment@gmail.com");
							c.setSubject("Go-card data bug");

							Functions.composeEmail(GoCardInfoActivity.this, c);

						}

					});
				}

				AlertDialog showDialog = b.create();

				showDialog.setOnDismissListener(new OnDismissListener() {

					@Override
					public void onDismiss(DialogInterface dialog) {
						try {
							finish();
						} catch (Exception e) {

						}
					}
				});

				showDialog.show();
			}
		}
	}

	private class ObtainGoCardHistoryTask extends ProgressAsyncTask<ArrayList<GoCardTransaction>> {

		public ObtainGoCardHistoryTask(Context c) {
			super(c, "Please wait...", "Loading Go-Card history");

		}

		protected ErrorObject<ArrayList<GoCardTransaction>> doInBackground(String... params) {

			ErrorObject<ArrayList<GoCardTransaction>> history = new ErrorObject<ArrayList<GoCardTransaction>>();
			String DATE_FORMAT_NOW = "dd-MMM-yyyy";

			Calendar cal = Calendar.getInstance();
			SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);

			String dateNow = sdf.format(cal.getTime());
			cal.add(Calendar.DATE, -7);
			String dateLast = sdf.format(cal.getTime());

			try {
				history.setItem(GoCardInfo.getGoCardTransactions(cardNumValue, cardPassValue,
						dateLast, dateNow));
			} catch (Exception e) {
				history.setException(new Exception("There was an error obtaining the history."));
			}
			return history;
		}

		protected void onPostExecute(ErrorObject<ArrayList<GoCardTransaction>> result) {
			super.onPostExecute(result);
			
			if (!result.hasException()) {
				loadHistory(result.getItem());
			} else {
				AlertDialog showDialog = Utils.showAlertDialog(GoCardInfoActivity.this, result
						.getException().getMessage());
				showDialog.setOnDismissListener(new OnDismissListener() {

					@Override
					public void onDismiss(DialogInterface dialog) {

						finish();
					}
				});
			}
		}
	}
}